<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>封装集合</title>
	</head>
	<body>
		<script>
			// 封装集合类
			function Set() {
				// 属性
				this.items = {};
				// 方法

				// 1. add(value) 向集合中添加一个新的项
				Set.prototype.add = function (value) {
					// 判断当前集合中是否包含了该元素
					if (this.has(value)) return false;
					// 将元素添加到集合中
					this.items[value] = value;
					return true;
				};

				// 2. has(value) 判断集合中是否含有该元素
				Set.prototype.has = function (value) {
					return this.items.hasOwnProperty(value);
				};

				// 3. remove(value) 移除集合中的某个元素
				Set.prototype.remove = function (value) {
					// 判断该集合中是否包含该元素
					if (!this.has(value)) return false;
					// 删除元素
					delete this.items[value];
					return true;
				};

				// 4. clear() 清空集合
				Set.prototype.clear = function () {
					this.items = {};
				};

				// 5. size() 获取集合包含元素个数
				Set.prototype.size = function () {
					return Object.keys(this.items).length;
				};

				// 6. value() 获取集合中所有元素的值
				Set.prototype.values = function () {
					return Object.keys(this.items);
				};

				// 集合间的操作

				// 1. 并集 A∪B
				Set.prototype.union = function (otherSet) {
					// this:集合对象A
					// otherSet:集合对象B
					// 1. 创建一个新的集合
					let unionSet = new Set();
					// 2. 将集合 A 中的所有元素添加到新集合中
					let values = this.values();
					for (let i = 0; i < values.length; i++) {
						unionSet.add(values[i]);
					}
					// 取出集合 B 中的元素，依次判断在新集合中是否存在，若不存在，则添加进新集合，若存在，则不添加
					values = otherSet.values();
					for (let i = 0; i < values.length; i++) {
						if (!unionSet.has(values[i])) {
							unionSet.add(values[i]);
						}
					}
					return unionSet;
				};

				// 2. 交集 A∩B
				Set.prototype.intersection = function (otherSet) {
					// this:集合对象A
					// otherSet:集合对象B
					// 1. 创建新的集合
					let intersectionSet = new Set();
					// 取出集合A中的元素，依次判断其在集合B中是否存在，若存在，就放入新集合中
					let values = this.values();
					for (let i = 0; i < values.length; i++) {
						let item = values[i];
						if (otherSet.has(item)) {
							intersectionSet.add(item);
						}
					}
					return intersectionSet;
				};

				// 3. 差集
				Set.prototype.diffrence = function (otherSet) {
					// this:集合对象A
					// otherSet:集合对象B
					// 1. 创建新的集合
					let diffrenceSet = new Set();
					// 取出集合A中的元素，依次判断其在集合B中是否存在，若不存在，就放入新集合中
					let values = this.values();
					for (let i = 0; i < values.length; i++) {
						let item = values[i];
						if (!otherSet.has(item)) {
							diffrenceSet.add(item);
						}
					}
					return diffrenceSet;
				};

				// 4. 子集   判断集合A是否是集合B的子集
				Set.prototype.subset = function (otherSet) {
					// this:集合A
					// otherSet:集合B
					// 遍历集合A中所有元素，如果发现集合A中所有元素在集合B中都存在，则证明是子集，返回true
					// 如果有一个不存在，就说明不是子集，返回false
					let values = this.values();
					for (let i = 0; i < values.length; i++) {
						let item = values[i];
						if (!otherSet.has(item)) {
							return false;
						}
					}
					return true;
				};
			}

			// 测试代码

			// // 1. 创建 Set 类对象
			// let set = new Set();

			// // 2. 添加元素
			// console.log(set.add('I'));
			// console.log(set.add('I'));
			// console.log(set.add('am'));
			// console.log(set.add('your'));
			// console.log(set.add('daddy'));
			// alert(set.values());
			// console.log('--------------------');

			// // 3. 删除元素
			// console.log(set.remove('your'));
			// console.log(set.remove('your'));
			// alert(set.values());
			// console.log('--------------------');

			// // 4. has(value)
			// console.log(set.has('daddy'));
			// console.log('--------------------');

			// // 5. clear() + size()
			// alert(set.size());
			// set.clear();
			// alert(set.size());

			// 并集 交集 差集 子集
			let setA = new Set();
			let setB = new Set();
			// setA : 1, 2, 3, 4
			setA.add('1');
			setA.add('2');
			setA.add('3');
			setA.add('4');
			// setB : 3, 4, 5, 6
			setB.add('3');
			setB.add('4');
			setB.add('5');
			setB.add('6');
			// setC : 3, 4
			let setC = new Set();
			setC.add('3');
			setC.add('4');
			// 求并集 交集 差集 子集
			let unionSet = setA.union(setB);
			let intersectionSet = setA.intersection(setB);
			let diffrenceSet = setA.diffrence(setB);
			alert(unionSet.values());
			alert(intersectionSet.values());
			alert(diffrenceSet.values());
			alert(setA.subset(setB)); // false
			alert(setC.subset(setB)); // true
		</script>
	</body>
</html>
